package com.limbo.showapp.activity;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.webkit.CookieManager;
import android.webkit.DownloadListener;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;

import com.limbo.showapp.R;
import com.limbo.showapp.base.SimpleBaseActivity;
import com.limbo.showapp.util.DisplayUtils;
import com.limbo.showapp.widget.SimpleOptionView;
import com.tencent.sonic.sdk.BuildConfig;
import com.tencent.sonic.sdk.SonicEngine;
import com.tencent.sonic.sdk.SonicRuntime;
import com.tencent.sonic.sdk.SonicSession;
import com.tencent.sonic.sdk.SonicSessionClient;
import com.tencent.sonic.sdk.SonicSessionConfig;

import java.io.File;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by wangqi on 2018/9/7.
 */

public class BrowserActivity extends SimpleBaseActivity {

    private SimpleOptionView simpleTileView;
    private ProgressBar progressBar;
    private String url;
    private WebView webView;
    private SonicSession sonicSession;

    @Override
    protected int getLayoutId() {
        return R.layout.activity_web_x5;
    }

    @Override
    protected void initView() {
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
        url = getIntent().getStringExtra("url");

        simpleTileView = findViewById(R.id.simpleTileView);
        webView = findViewById(R.id.webview);
        progressBar = findViewById(R.id.progressBar);

        DisplayUtils.initAfterSetContentView(this, simpleTileView);
    }

    @Override
    protected void initData() {
        // step 1: Initialize sonic engine if necessary, or maybe u can do this when application created
        SonicSessionClientImpl sonicSessionClient = null;

        // step 2: Create SonicSession
        sonicSession = SonicEngine.getInstance().createSession(url, new SonicSessionConfig.Builder().build());
        if (null != sonicSession) {
            sonicSession.bindClient(sonicSessionClient = new SonicSessionClientImpl());
        } else {
            // this only happen when a same sonic session is already running,
            // u can comment following codes to feedback as a default mode.
            throw new UnknownError("create session fail!");
        }

        // step 3: BindWebView for sessionClient and bindClient for SonicSession
        // in the real world, the init flow may cost a long time as startup
        // runtime、init configs....
        webView.setWebViewClient(new WebViewClient() {

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
//                view.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
//                view.loadUrl(url);
                return super.shouldOverrideUrlLoading(view, url);
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                if (sonicSession != null) {
                    sonicSession.getSessionClient().pageFinish(url);
                }
            }

            @TargetApi(21)
            @Override
            public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
                return shouldInterceptRequest(view, request.getUrl().toString());
            }

            @Override
            public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
                if (sonicSession != null) {
                    //step 6: Call sessionClient.requestResource when host allow the application
                    // to return the local data .
                    return (WebResourceResponse) sonicSession.getSessionClient().requestResource(url);
                }
                return null;
            }
        });

        webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                if (newProgress == 100) {
                    progressBar.setVisibility(View.GONE);
                } else {
                    if (progressBar.getVisibility() == View.GONE) {
                        progressBar.setVisibility(View.VISIBLE);
                    }
                    progressBar.setProgress(newProgress);
                }
            }

            @Override
            public void onReceivedTitle(WebView view, String title) {
                simpleTileView.setTitle(title);
            }
        });

        webView.setDownloadListener(new DownloadListener() {
            @Override
            public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
                Uri uri = Uri.parse(url);
                Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                startActivity(intent);
            }
        });


        WebSettings webSettings = webView.getSettings();

        // step 4: bind javascript
        // note:if api level lower than 17(android 4.2), addJavascriptInterface has security
        // issue, please use x5 or see https://developer.android.com/reference/android/webkit/
        // WebView.html#addJavascriptInterface(java.lang.Object, java.lang.String)
        webSettings.setJavaScriptEnabled(true);
//        webView.addJavascriptInterface(new SonicJavaScriptInterface(sonicSessionClient, intent), "sonic");

        // init webview settings
        webSettings.setAllowContentAccess(true);
        webSettings.setDatabaseEnabled(true);
        webSettings.setDomStorageEnabled(true);
        webSettings.setAppCacheEnabled(true);
        webSettings.setSavePassword(false);
        webSettings.setSaveFormData(false);
        webSettings.setUseWideViewPort(true);
        webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
        //设置webview自适应屏幕
        webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
        webSettings.setLoadWithOverviewMode(true);


        // step 5: webview is ready now, just tell session client to bind
        if (sonicSessionClient != null) {
            sonicSessionClient.bindWebView(webView);
            sonicSessionClient.clientReady();
        } else { // default mode
            webView.loadUrl(url);
        }
    }

    @Override
    public void onBackPressed() {
        if (webView.canGoBack()) {
            webView.goBack();
        } else {
            super.onBackPressed();
        }
    }

    @Override
    protected void onDestroy() {
        if (null != sonicSession) {
            sonicSession.destroy();
            sonicSession = null;
        }
        super.onDestroy();
    }

    public static class SonicRuntimeImpl extends SonicRuntime {

        public SonicRuntimeImpl(Context context) {
            super(context);
        }

        /**
         * 获取用户UA信息，这里的返回值会放在header的UserAgent中
         *
         * @return
         */
        @Override
        public String getUserAgent() {
            return "";
        }

        /**
         * 获取用户ID信息，避免多个用户切换可能使用到相同的缓存
         *
         * @return
         */
        @Override
        public String getCurrentUserAccount() {
            return "sonic-demo-master";
        }

        @Override
        public String getCookie(String url) {
            CookieManager cookieManager = CookieManager.getInstance();
            return cookieManager.getCookie(url);
        }

        @Override
        public void log(String tag, int level, String message) {
            switch (level) {
                case Log.ERROR:
                    Log.e(tag, message);
                    break;
                case Log.INFO:
                    Log.i(tag, message);
                    break;
                default:
                    Log.d(tag, message);
            }
        }

        @Override
        public Object createWebResourceResponse(String mimeType, String encoding, InputStream data, Map<String, String> headers) {
            WebResourceResponse resourceResponse = new WebResourceResponse(mimeType, encoding, data);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                resourceResponse.setResponseHeaders(headers);
            }
            return resourceResponse;
        }

        @Override
        public void showToast(CharSequence text, int duration) {

        }

        @Override
        public void notifyError(SonicSessionClient client, String url, int errorCode) {

        }

        // 这里可以设置某个url是否为SonicUrl，如果指定为不是，则不会通过Sonic的方式加载url。
        @Override
        public boolean isSonicUrl(String url) {
            return true;
        }

        @Override
        public boolean setCookie(String url, List<String> cookies) {
            if (!TextUtils.isEmpty(url) && cookies != null && cookies.size() > 0) {
                CookieManager cookieManager = CookieManager.getInstance();
                for (String cookie : cookies) {
                    cookieManager.setCookie(url, cookie);
                }
                return true;
            }
            return false;
        }

        // 判断网络连接情况
        @Override
        public boolean isNetworkValid() {
            return true;
        }

        @Override
        public void postTaskToThread(Runnable task, long delayMillis) {
            Thread thread = new Thread(task, "SonicThread");
            thread.start();
        }

        @Override
        public File getSonicCacheDir() {
            if (BuildConfig.DEBUG) {
                String path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "sonic/";
                File file = new File(path.trim());
                if (!file.exists()) {
                    file.mkdir();
                }
                return file;
            }
            return super.getSonicCacheDir();
        }

        @Override
        public String getHostDirectAddress(String url) {
            return null;
        }
    }

    public static class SonicSessionClientImpl extends SonicSessionClient {

        private WebView webView;

        public void bindWebView(WebView webView) {
            this.webView = webView;
        }

        public WebView getWebView() {
            return webView;
        }

        @Override
        public void loadUrl(String url, Bundle extraData) {
            webView.loadUrl(url);
        }

        @Override
        public void loadDataWithBaseUrl(String baseUrl, String data, String mimeType, String encoding, String historyUrl) {
            webView.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl);
        }


        @Override
        public void loadDataWithBaseUrlAndHeader(String baseUrl, String data, String mimeType, String encoding, String historyUrl, HashMap<String, String> headers) {
            loadDataWithBaseUrl(baseUrl, data, mimeType, encoding, historyUrl);
        }

        public void destroy() {
            if (null != webView) {
                webView.destroy();
                webView = null;
            }
        }

    }

    public static void OpenActivity(Context context, String url) {
        Intent intent = new Intent(context, BrowserActivity.class);
        intent.putExtra("url", url);
        context.startActivity(intent);
    }
}
